package mirrormonkey.core.client;

import mirrormonkey.core.member.ConstructorData;
import mirrormonkey.core.messages.EntityChangeMessage;
import mirrormonkey.framework.EntityProvider;
import mirrormonkey.framework.entity.StaticEntityData;
import mirrormonkey.framework.entity.SyncEntity;

import com.jme3.network.Message;
import com.jme3.network.MessageConnection;
import com.jme3.network.MessageListener;

public class EntityChangeListener implements MessageListener<MessageConnection> {

	protected final EntityProvider entityProvider;

	protected final ClientCoreModule module;

	public EntityChangeListener(EntityProvider entityProvider,
			ClientCoreModule module) {
		this.entityProvider = entityProvider;
		this.module = module;
	}

	@Override
	public void messageReceived(MessageConnection source, Message message) {
		try {
			EntityChangeMessage castMessage = (EntityChangeMessage) message;
			Class<? extends SyncEntity> entityClass = (Class<? extends SyncEntity>) Class
					.forName(castMessage.className);

			ClientEntityData data = (ClientEntityData) entityProvider
					.getData(castMessage.entityId);
			StaticEntityData oldStaticData = data.getStaticData(source);
			SyncEntity oldReference = data.getEntity();

			StaticEntityData newStaticData = entityProvider.getStaticData(
					entityClass, oldStaticData.connectedClass);
			ConstructorData constr = newStaticData.getData(
					castMessage.constrId, ConstructorData.class);
			SyncEntity newReference = constr
					.newEntity(castMessage.packedParams);

			data.setStaticData(newStaticData);
			data.newReferenceArrived(newReference);

			module.notifyChangeListeners(data, oldStaticData, newStaticData,
					oldReference, module.connectionInfo);
		} catch (RuntimeException e) {
			throw e;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}
